package com.fy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fy.mapper.AnnouncementMapper;
import com.fy.pojo.dto.announcement.AddAnnouncementDTO;
import com.fy.pojo.dto.announcement.AnnouncementDTO;
import com.fy.pojo.dto.announcement.AnnouncementQueryDTO;
import com.fy.pojo.dto.announcement.UpdateAnnouncementDTO;
import com.fy.pojo.entity.Announcement;
import com.fy.pojo.vo.admin.AdminAnnouncementVO;
import com.fy.service.AnnouncementService;
import com.fy.utils.DateFormatter;
import com.fy.utils.result.PageResult;
import com.fy.utils.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Announcement>
    implements AnnouncementService {

  @Autowired
  private AnnouncementMapper announcementMapper;

  @Override
  @Transactional
  public Result publishAnnouncement(AnnouncementDTO announcementDTO) {
    log.info("开始发布公告，公告信息：{}", announcementDTO);

    try {
      // 1. 参数校验
      if (StringUtils.isBlank(announcementDTO.getTitle())) {
        return Result.error("公告标题不能为空");
      }
      if (StringUtils.isBlank(announcementDTO.getType())) {
        return Result.error("公告类型不能为空");
      }
      if (StringUtils.isBlank(announcementDTO.getContent())) {
        return Result.error("公告内容不能为空");
      }
      if (announcementDTO.getImportance() == null) {
        return Result.error("重要程度不能为空");
      }

      // 2. 转换为实体
      Announcement announcement = new Announcement();
      BeanUtils.copyProperties(announcementDTO, announcement);

      // 3. 处理展示时间
      try {
        announcement.setShowTime(Timestamp.valueOf(announcementDTO.getShowTime()));
      } catch (IllegalArgumentException e) {
        return Result.error("展示时间格式不正确");
      }

      // 4. 设置创建和更新时间
      LocalDateTime now = LocalDateTime.now();
      announcement.setCreateTime(Timestamp.valueOf(now));
      announcement.setUpdateTime(Timestamp.valueOf(now));

      // 5. 保存公告
      int rows = announcementMapper.insert(announcement);
      if (rows <= 0) {
        return Result.error("公告发布失败");
      }

      log.info("公告发布成功，公告ID：{}", announcement.getId());
      return Result.success("公告发布成功");

    } catch (Exception e) {
      log.error("公告发布异常", e);
      return Result.error("公告发布失败：" + e.getMessage());
    }
  }

  @Override
  public Result<PageResult> getAnnouncementList(AnnouncementQueryDTO queryDTO) {
    log.info("开始查询公告列表，查询参数：{}", queryDTO);

    try {
      // 1. 构建查询条件
      LambdaQueryWrapper<Announcement> queryWrapper = new LambdaQueryWrapper<>();

      // 2. 标题模糊查询
      if (StringUtils.isNotBlank(queryDTO.getTitle())) {
        queryWrapper.like(Announcement::getTitle, queryDTO.getTitle());
      }

      // 3. 类型精确匹配
      if (StringUtils.isNotBlank(queryDTO.getType())) {
        queryWrapper.eq(Announcement::getType, queryDTO.getType());
      }

      // 4. 状态查询
      if (queryDTO.getStatus() != null) {
        // 可以根据实际需求添加状态的处理逻辑
        queryWrapper.eq(Announcement::getStatus, queryDTO.getStatus());
      }

      // 5. 按展示时间倒序
      queryWrapper.orderByDesc(Announcement::getShowTime);

      // 6. 分页查询
      Page<Announcement> page = new Page<>(queryDTO.getPageNo(), queryDTO.getPageSize());
      Page<Announcement> announcementPage = announcementMapper.selectPage(page, queryWrapper);

      // 7. 转换为VO
      List<AdminAnnouncementVO> announcementVOList = announcementPage.getRecords().stream()
          .map(announcement -> {
            AdminAnnouncementVO vo = new AdminAnnouncementVO();
            BeanUtils.copyProperties(announcement, vo);
            // 格式化时间
            vo.setShowTime(DateFormatter.getTimestampStringByDate(announcement.getShowTime()));
            vo.setCreateTime(DateFormatter.getTimestampStringByDate(announcement.getCreateTime()));
            return vo;
          })
          .collect(Collectors.toList());

      // 8. 封装分页结果
      PageResult pageResult = new PageResult();
      pageResult.setList(announcementVOList);
      pageResult.setPageNo(queryDTO.getPageNo());
      pageResult.setPageSize(queryDTO.getPageSize());
      pageResult.setTotalCount(announcementPage.getTotal());

      return Result.success(pageResult);

    } catch (Exception e) {
      log.error("查询公告列表异常", e);
      return Result.error("查询公告列表失败：" + e.getMessage());
    }
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Result updateAnnouncement(UpdateAnnouncementDTO updateAnnouncementDTO) {
    try {
      // 1. 参数校验
      if (updateAnnouncementDTO.getId() == null) {
        return Result.error("公告ID不能为空");
      }

      // 2. 检查公告是否存在
      Announcement announcement = announcementMapper.selectById(updateAnnouncementDTO.getId());
      if (announcement == null) {
        return Result.error("公告不存在");
      }

      // 3. 更新公告信息
      Announcement updateAnnouncement = new Announcement();
      BeanUtils.copyProperties(updateAnnouncementDTO, updateAnnouncement);

      // 4. 处理展示时间
      try {
        updateAnnouncement.setShowTime(Timestamp.valueOf(updateAnnouncementDTO.getShowTime()));
      } catch (IllegalArgumentException e) {
        return Result.error("展示时间格式不正确");
      }

      // 5. 设置更新时间
      updateAnnouncement.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));

      // 6. 执行更新
      int rows = announcementMapper.updateById(updateAnnouncement);
      if (rows > 0) {
        return Result.success("公告更新成功");
      } else {
        return Result.error("公告更新失败");
      }
    } catch (Exception e) {
      log.error("更新公告失败", e);
      throw new RuntimeException("更新公告失败：" + e.getMessage());
    }
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Result addAnnouncement(AddAnnouncementDTO addAnnouncementDTO) {
    try {
      // 1. 参数校验
      if (StringUtils.isBlank(addAnnouncementDTO.getTitle())) {
        return Result.error("公告标题不能为空");
      }
      if (StringUtils.isBlank(addAnnouncementDTO.getType())) {
        return Result.error("公告类型不能为空");
      }
      if (StringUtils.isBlank(addAnnouncementDTO.getContent())) {
        return Result.error("公告内容不能为空");
      }
      if (StringUtils.isBlank(addAnnouncementDTO.getShowTime())) {
        return Result.error("展示时间不能为空");
      }

      // 2. 转换为实体
      Announcement announcement = new Announcement();
      BeanUtils.copyProperties(addAnnouncementDTO, announcement);

      // 3. 处理展示时间
      try {
        announcement.setShowTime(Timestamp.valueOf(addAnnouncementDTO.getShowTime()));
      } catch (IllegalArgumentException e) {
        return Result.error("展示时间格式不正确");
      }

      // 4. 设置创建和更新时间
      LocalDateTime now = LocalDateTime.now();
      announcement.setCreateTime(Timestamp.valueOf(now));
      announcement.setUpdateTime(Timestamp.valueOf(now));
      // 根据showTime与当前时间判断是否显示然后设置status
      if (announcement.getShowTime().before(Timestamp.valueOf(now))) {
        announcement.setStatus(1);
      } else {
        announcement.setStatus(0);
      }

      // 5. 保存公告
      boolean success = save(announcement);
      if (success) {
        return Result.success("公告添加成功");
      } else {
        return Result.error("公告添加失败");
      }
    } catch (Exception e) {
      log.error("添加公告失败", e);
      throw new RuntimeException("添加公告失败：" + e.getMessage());
    }
  }
}